from django.contrib.auth.models import AbstractUser, BaseUserManager
from django.db import models
from django.core.validators import RegexValidator
from django.utils import timezone
from exams.models import LogistQuestion


class UserManager(BaseUserManager):
    """自定义用户管理器"""
    
    def create_user(self, email, name, role, password=None, **extra_fields):
        """创建并保存普通用户"""
        if not email:
            raise ValueError('用户必须有邮箱地址')
        if not name:
            raise ValueError('用户必须有姓名')
        if not role:
            raise ValueError('用户必须有角色')
            
        email = self.normalize_email(email)
        user = self.model(email=email, name=name, role=role, **extra_fields)
        user.set_password(password)
        user.save(using=self._db)
        return user
    
    def create_superuser(self, email, name, role, password=None, **extra_fields):
        """创建并保存超级用户"""
        extra_fields.setdefault('is_staff', True)
        extra_fields.setdefault('is_superuser', True)
        
        if extra_fields.get('is_staff') is not True:
            raise ValueError('超级用户必须设置is_staff=True')
        if extra_fields.get('is_superuser') is not True:
            raise ValueError('超级用户必须设置is_superuser=True')
        
        return self.create_user(email, name, role, password, **extra_fields)


class User(AbstractUser):
    """自定义用户模型"""
    
    ROLE_CHOICES = [
        ('hr', 'HR招聘官'),
        ('candidate', '候选人'),
    ]
    
    GENDER_CHOICES = [
        ('male', '男'),
        ('female', '女'),
    ]
    
    # 禁用默认的username字段
    username = None
    
    # 使用email作为登录字段
    email = models.EmailField(unique=True, verbose_name='邮箱')
    
    # 用户基本信息
    name = models.CharField(max_length=100, verbose_name='姓名')
    
    # 用户角色
    role = models.CharField(
        max_length=20, 
        choices=ROLE_CHOICES,
        verbose_name='角色'
    )
    
    # 性别字段
    gender = models.CharField(
        max_length=10,
        choices=GENDER_CHOICES,
        default='female',  # 默认设置为女性
        verbose_name='性别'
    )
    
    # 公司信息
    company = models.CharField(max_length=255, blank=True, verbose_name='所属公司')

    # 手机号码（可选）
    phone_regex = RegexValidator(
        regex=r'^\+?1?\d{9,15}$',
        message="手机号格式不正确，请输入有效的手机号码。"
    )
    phone = models.CharField(
        validators=[phone_regex], 
        max_length=17, 
        blank=True,
        verbose_name='手机号'
    )
    
    # 头像URL（可选）
    avatar = models.URLField(blank=True, verbose_name='头像')
    
    # 创建时间和更新时间
    created_at = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
    updated_at = models.DateTimeField(auto_now=True, verbose_name='更新时间')
    
    # 指定email作为登录字段
    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = ['name', 'role']
    
    # 使用自定义的用户管理器
    objects = UserManager()
    
    class Meta:
        verbose_name = '用户'
        verbose_name_plural = '用户'
        db_table = 'spark_user'
    
    def __str__(self):
        return f"{self.name} ({self.email})"
    
    @property
    def is_hr(self):
        """判断是否为HR"""
        return self.role == 'hr'
    
    @property
    def is_candidate(self):
        """判断是否为候选人"""
        return self.role == 'candidate'


# #####################################################################
# # 2. 职位与简历筛选 (Job Posting and Resume Screening)
# #####################################################################

class JobPosting(models.Model):
    """HR发布的职位信息"""
    
    # 职位基本信息
    title = models.CharField(max_length=255, verbose_name='职位名称')
    department = models.CharField(max_length=100, verbose_name='部门')
    location = models.CharField(max_length=100, verbose_name='工作地点')
    employment_type = models.CharField(
        max_length=20,
        choices=[
            ('full_time', '全职'),
            ('part_time', '兼职'),
            ('internship', '实习'),
            ('contract', '合同'),
            ('remote', '远程'),
        ],
        default='full_time',
        verbose_name='雇佣类型'
    )
    
    # 职位要求
    education = models.CharField(max_length=200, verbose_name='教育要求')
    working_experience = models.CharField(max_length=200, verbose_name='工作经验要求')
    requirements_skills = models.TextField(verbose_name='技能要求')
    soft_skills = models.TextField(verbose_name='软技能要求')
    
    # 职位描述
    description = models.TextField(verbose_name='职位描述')
    
    # 招聘信息
    number_of_hires = models.PositiveIntegerField(default=1, verbose_name='招聘人数')
    salary_range = models.CharField(max_length=100, verbose_name='薪资范围')
    benefits = models.TextField(verbose_name='福利待遇')
    
    # 联系方式
    contact_email = models.EmailField(blank=True, verbose_name='联系邮箱')
    
    # 时间信息
    application_deadline = models.DateTimeField(null=True, blank=True, verbose_name='申请截止时间')
    
    # 状态信息
    is_active = models.BooleanField(default=True, verbose_name='是否开放招聘')
    required_match_score = models.FloatField(default=0.6, verbose_name='要求匹配度阈值')  # 默认60%
    
    # 创建信息
    created_at = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
    updated_at = models.DateTimeField(auto_now=True, verbose_name='更新时间')
    created_by = models.ForeignKey(
        User,
        on_delete=models.CASCADE,
        related_name='job_postings',
        limit_choices_to={'role': 'hr'},
        verbose_name='发布人'
    )

    def __str__(self):
        return f"{self.title} - {self.department}"

    class Meta:
        verbose_name = '职位发布'
        verbose_name_plural = verbose_name
        ordering = ['-created_at']


class JobApplication(models.Model):
    """求职申请，连接候选人与职位"""
    STATUS_CHOICES = [
        ('pending', '待筛选'),
        ('screened_pass', '筛选通过'),
        ('screened_fail', '筛选失败'),
        ('interviewing', '面试中'),
        ('completed', '流程已完成'),
    ]

    candidate = models.ForeignKey(
        User,
        on_delete=models.CASCADE,
        related_name='applications',
        limit_choices_to={'role': 'candidate'},  # 限制只能是候选人
        verbose_name='申请人'
    )
    job_posting = models.ForeignKey(
        JobPosting,
        on_delete=models.CASCADE,
        related_name='applications',
        verbose_name='申请职位'
    )
    resume_file = models.FileField(upload_to='resumes/', verbose_name='简历文件')
    
    # 简历分析结果
    job_fit_score = models.FloatField(null=True, blank=True, verbose_name='岗位匹配度得分')
    core_skills_matched = models.JSONField(default=list, verbose_name='匹配的核心技能')
    soft_skills_detected = models.JSONField(default=list, verbose_name='检测到的软技能')
    education_summary = models.TextField(blank=True, verbose_name='教育背景摘要')
    experience_summary = models.TextField(blank=True, verbose_name='工作经验摘要')
    highlights = models.JSONField(default=list, verbose_name='简历亮点')
    interview_recommendation = models.CharField(
        max_length=50,
        choices=[
            ('recommended', '推荐进入面试'),
            ('conditional', '有条件推荐'),
            ('not_recommended', '暂不推荐'),
        ],
        blank=True,
        verbose_name='面试推荐'
    )
    
    # 详细的筛选反馈（用于失败情况）
    screening_feedback = models.JSONField(default=list, verbose_name='筛选反馈详情')
    screening_suggestions = models.JSONField(default=list, verbose_name='改进建议')
    
    # 申请状态
    status = models.CharField(max_length=50, choices=STATUS_CHOICES, default='pending', verbose_name='申请状态')
    applied_at = models.DateTimeField(auto_now_add=True, verbose_name='申请时间')
    
    # 面试相关字段
    self_introduction_video = models.FileField(upload_to='videos/self_intro/', blank=True, null=True, verbose_name='30秒自我介绍视频文件')

    def __str__(self):
        return f'{self.candidate.name} 申请 {self.job_posting.title}'

    class Meta:
        unique_together = ('candidate', 'job_posting')
        verbose_name = '求职申请'
        verbose_name_plural = verbose_name
        ordering = ['-applied_at']


# #####################################################################
# # 3. 新题型与面试定义 (New Question Type and Interview Definition)
# #####################################################################

class VideoQuestion(models.Model):
    """视频简答题库"""
    
    CATEGORY_CHOICES = [
        ('innovation', '创新思考类'),
        ('pressure', '压力应对类'),
        ('professional', '专业技能类'),
    ]
    
    # 基本信息
    title = models.CharField(max_length=255, verbose_name='题目标题')
    content = models.TextField(verbose_name='题目内容')
    topic_tags = models.CharField(max_length=255, blank=True, verbose_name='主题标签 (逗号分隔)')
    
    # 新增字段
    excellent_answer_example = models.TextField(verbose_name='优秀回答示例')
    scoring_criteria = models.TextField(verbose_name='评分标准')
    answer_duration = models.PositiveIntegerField(verbose_name='回答时间长度(秒)')
    category = models.CharField(
        max_length=20, 
        choices=CATEGORY_CHOICES,
        verbose_name='所属类别'
    )
    applicable_positions = models.JSONField(
        default=list,
        verbose_name='适用岗位(JSON数组)'
    )
    
    # 创建信息
    created_at = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
    created_by = models.ForeignKey(
        User,
        on_delete=models.SET_NULL,
        null=True,
        related_name='video_questions',
        limit_choices_to={'role': 'hr'},
        verbose_name='创建人'
    )

    def __str__(self):
        return self.title

    class Meta:
        verbose_name = '视频简答题'
        verbose_name_plural = verbose_name


class VoiceProfile(models.Model):
    """语音配置文件，用于音频合成"""
    
    VOICE_TYPE_CHOICES = [
        ('male_1', '男声1'),
        ('male_2', '男声2'),
        ('male_3', '男声3'),
        ('female_1', '女声1'),
        ('female_2', '女声2'),
        ('female_3', '女声3'),
    ]
    
    name = models.CharField(max_length=100, verbose_name='语音名称')
    voice_type = models.CharField(
        max_length=20,
        choices=VOICE_TYPE_CHOICES,
        verbose_name='语音类型'
    )
    description = models.TextField(blank=True, verbose_name='语音描述')
    sample_audio_url = models.URLField(blank=True, verbose_name='示例音频URL')
    is_active = models.BooleanField(default=True, verbose_name='是否可用')
    
    # 讯飞发音人配置
    xunfei_vcn = models.CharField(
        max_length=50,
        default='x4_lingxiaoxuan_oral',
        verbose_name='讯飞发音人代码'
    )
    
    # 语音参数配置
    speed = models.FloatField(default=1.0, verbose_name='语速倍数')
    pitch = models.FloatField(default=1.0, verbose_name='音调倍数')
    volume = models.FloatField(default=1.0, verbose_name='音量倍数')
    
    created_at = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
    
    def get_voice_config(self):
        """获取语音配置字典，用于TTS API调用"""
        return {
            'vcn': self.xunfei_vcn,
            'speed': int(self.speed * 50),  # 转换为讯飞API的0-100范围
            'pitch': int(self.pitch * 50),
            'volume': int(self.volume * 50),
        }
    
    def __str__(self):
        return f"{self.name} ({self.get_voice_type_display()})"
    
    class Meta:
        verbose_name = '语音配置'
        verbose_name_plural = verbose_name


class SynthesizedAudio(models.Model):
    """合成的音频文件记录"""
    
    STATUS_CHOICES = [
        ('pending', '待合成'),
        ('processing', '合成中'),
        ('completed', '已完成'),
        ('failed', '合成失败'),
    ]
    
    question = models.ForeignKey(
        VideoQuestion,
        on_delete=models.CASCADE,
        related_name='synthesized_audios',
        verbose_name='关联题目'
    )
    voice_profile = models.ForeignKey(
        VoiceProfile,
        on_delete=models.CASCADE,
        related_name='synthesized_audios',
        verbose_name='使用的语音配置'
    )
    audio_file = models.FileField(upload_to='synthesized_audio/', verbose_name='合成音频文件')
    text_content = models.TextField(verbose_name='合成的文本内容')
    duration = models.FloatField(null=True, blank=True, verbose_name='音频时长(秒)')
    file_size = models.PositiveIntegerField(null=True, blank=True, verbose_name='文件大小(字节)')
    
    # 新增状态字段
    status = models.CharField(
        max_length=20,
        choices=STATUS_CHOICES,
        default='pending',
        verbose_name='合成状态'
    )
    error_message = models.TextField(blank=True, verbose_name='错误信息')
    
    created_at = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
    updated_at = models.DateTimeField(auto_now=True, verbose_name='更新时间')
    
    def __str__(self):
        return f"{self.question.title} - {self.voice_profile.name}"
    
    class Meta:
        verbose_name = '合成音频'
        verbose_name_plural = verbose_name
        unique_together = ['question', 'voice_profile']


class InterviewTemplate(models.Model):
    """面试模板，将笔试题和视频题组合成一个面试流程"""
    title = models.CharField(max_length=255, verbose_name='面试模板标题')
    description = models.TextField(blank=True, verbose_name='模板描述')
    job_posting = models.OneToOneField(
        JobPosting,
        on_delete=models.CASCADE,
        related_name='interview_template',
        verbose_name='关联职位'
    )
    created_by = models.ForeignKey(
        User,
        on_delete=models.SET_NULL,
        null=True,
        related_name='interview_templates',
        limit_choices_to={'role': 'hr'},
        verbose_name='创建人'
    )
    logist_questions = models.ManyToManyField(
        LogistQuestion,
        blank=True,
        related_name='interview_templates',
        verbose_name='笔试题'
    )
    video_questions = models.ManyToManyField(
        VideoQuestion,
        blank=True,
        related_name='interview_templates',
        verbose_name='视频题'
    )
    
    # 六个维度的权重配置
    resume_match_weight = models.FloatField(default=0.25, verbose_name='简历匹配权重')
    professional_skill_weight = models.FloatField(default=0.20, verbose_name='专业技能权重')
    logical_thinking_weight = models.FloatField(default=0.15, verbose_name='逻辑思维能力权重')
    innovation_weight = models.FloatField(default=0.15, verbose_name='创新能力权重')
    stress_management_weight = models.FloatField(default=0.15, verbose_name='压力应对权重')
    expression_weight = models.FloatField(default=0.10, verbose_name='语言能力权重')
    
    # 默认语音配置
    default_voice_profile = models.ForeignKey(
        VoiceProfile,
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        related_name='default_templates',
        verbose_name='默认语音配置'
    )
    
    # 权重验证方法
    def clean(self):
        from django.core.exceptions import ValidationError
        total_weight = (
            self.resume_match_weight + 
            self.professional_skill_weight + 
            self.logical_thinking_weight + 
            self.innovation_weight + 
            self.stress_management_weight + 
            self.expression_weight
        )
        if abs(total_weight - 1.0) > 0.001:  # 允许小的浮点数误差
            raise ValidationError('六个维度的权重总和必须等于1.0')
    
    def save(self, *args, **kwargs):
        self.clean()
        super().save(*args, **kwargs)

    def __str__(self):
        return self.title

    class Meta:
        verbose_name = '面试模板'
        verbose_name_plural = verbose_name


# #####################################################################
# # 4. 面试执行与结果分析 (Interview Execution and Analysis)
# #####################################################################

class InterviewSession(models.Model):
    """面试会话，追踪候选人完成一次完整面试的进度和核心结果"""
    STATUS_CHOICES = [
        ('pending', '待开始'),
        ('logic_test', '笔试进行中'),
        ('video_interview', '视频面试进行中'),
        ('generating_report', '待生成报告'),
        ('completed', '已完成'),
    ]

    application = models.OneToOneField(
        JobApplication,
        on_delete=models.CASCADE,
        related_name='interview_session',
        verbose_name='关联申请'
    )
    template = models.ForeignKey(
        InterviewTemplate,
        on_delete=models.PROTECT,  # 保护模板，不允许删除正在使用的模板
        related_name='sessions',
        verbose_name='使用模板'
    )
    status = models.CharField(max_length=50, choices=STATUS_CHOICES, default='pending', verbose_name='面试状态')
    logical_thinking_score = models.FloatField(null=True, blank=True, verbose_name='逻辑思维能力得分')
    started_at = models.DateTimeField(null=True, blank=True, verbose_name='开始时间')
    completed_at = models.DateTimeField(null=True, blank=True, verbose_name='完成时间')

    def __str__(self):
        return f"Session for {self.application}"

    class Meta:
        verbose_name = '面试会话'
        verbose_name_plural = verbose_name


class VideoAnswer(models.Model):
    """存储视频回答和AI分析的4个维度得分"""
    session = models.ForeignKey(
        InterviewSession,
        on_delete=models.CASCADE,
        related_name='video_answers',
        verbose_name='所属会话'
    )
    question = models.ForeignKey(
        VideoQuestion,
        on_delete=models.PROTECT,
        related_name='answers',
        verbose_name='对应问题'
    )
    video_url = models.FileField(upload_to='videos/answers/', verbose_name='视频回答文件')
    
    # 四个维度的得分
    expression_score = models.FloatField(null=True, blank=True, verbose_name='语言表达能力得分')
    innovation_score = models.FloatField(null=True, blank=True, verbose_name='创新思考能力得分')
    professional_skill_score = models.FloatField(null=True, blank=True, verbose_name='专业技能能力得分')
    stress_management_score = models.FloatField(null=True, blank=True, verbose_name='压力应对能力得分')
    
    # 新增：从视频中提取的文本信息
    extracted_text = models.TextField(blank=True, verbose_name='从视频中提取的文本内容')
    text_confidence = models.FloatField(null=True, blank=True, verbose_name='文本提取置信度(0-1)')
    
    # 新增：大模型对文本内容的AI反馈
    ai_feedback = models.TextField(blank=True, verbose_name='AI对回答内容的反馈')
    ai_score = models.FloatField(null=True, blank=True, verbose_name='AI对回答内容的评分')
    ai_keywords = models.JSONField(default=list, verbose_name='AI提取的关键词')
    ai_sentiment = models.CharField(
        max_length=20,
        choices=[
            ('positive', '积极'),
            ('neutral', '中性'),
            ('negative', '消极'),
        ],
        blank=True,
        verbose_name='AI情感分析结果'
    )
    
    answered_at = models.DateTimeField(auto_now_add=True, verbose_name='回答时间')

    def __str__(self):
        return f"Answer to '{self.question.content[:20]}...' in {self.session}"

    class Meta:
        verbose_name = '视频回答与分析'
        verbose_name_plural = verbose_name


# 替换现有的AudioAnalysis模型
class AudioAnalysis(models.Model):
    """音频整体分析模型 - 基于音频处理同学的算法设计"""
    video_answer = models.OneToOneField(
        VideoAnswer,
        on_delete=models.CASCADE,
        related_name='audio_analysis',
        verbose_name='关联视频回答'
    )

    GENDER_CHOICES = [
        ('male', '男性'),
        ('female', '女性'),
    ]
    gender = models.CharField(max_length=10, choices=GENDER_CHOICES, null=True, blank=True, verbose_name="说话者性别")

    analyzed_at = models.DateTimeField(auto_now_add=True, verbose_name="分析时间")

    # 语音转文字相关
    transcribed_text = models.TextField(null=True, blank=True, verbose_name="语音转文字内容")
    word_count = models.IntegerField(null=True, blank=True, verbose_name="转录字数/词数")
    speech_duration_seconds = models.FloatField(null=True, blank=True, verbose_name="实际说话时长（秒）")

    # 综合得分
    overall_audio_score = models.FloatField(null=True, blank=True, verbose_name="音频综合得分")

    # 语速分析
    speed_score = models.FloatField(null=True, blank=True, verbose_name="语速得分")
    speech_rate_syllables_per_second = models.FloatField(null=True, blank=True, verbose_name="语速（音节/秒）")

    # 音高分析
    pitch_score = models.FloatField(null=True, blank=True, verbose_name="音高得分")
    average_pitch_frequency_hz = models.FloatField(null=True, blank=True, verbose_name="平均基频（Hz）")

    # 音量分析
    volume_score = models.FloatField(null=True, blank=True, verbose_name="音量得分")
    average_volume_db = models.FloatField(null=True, blank=True, verbose_name="平均音量（dB）")

    # 停顿分析
    pause_score = models.FloatField(null=True, blank=True, verbose_name="停顿得分")
    total_pause_frequency_per_second = models.FloatField(null=True, blank=True, verbose_name="总停顿频次（次/秒）")

    # 流利度分析
    fluency_score = models.FloatField(null=True, blank=True, verbose_name="流利度总得分")
    articulation_rate_syllables_per_second = models.FloatField(null=True, blank=True, verbose_name="发音速率（音节/秒）")
    articulation_rate_score = models.FloatField(null=True, blank=True, verbose_name="发音速率得分")
    correction_count_per_second = models.FloatField(null=True, blank=True, verbose_name="修正次数（次/秒）")
    correction_count_score = models.FloatField(null=True, blank=True, verbose_name="修正次数得分")
    f2_slope_hz_per_ms = models.FloatField(null=True, blank=True, verbose_name="F2轨迹斜率（Hz/ms）")
    f2_slope_score = models.FloatField(null=True, blank=True, verbose_name="F2轨迹斜率得分")

    # 分析状态
    analysis_status = models.CharField(
        max_length=20,
        choices=[
            ('pending', '待分析'),
            ('processing', '分析中'),
            ('completed', '已完成'),
            ('failed', '分析失败'),
        ],
        default='pending',
        verbose_name='分析状态'
    )
    error_message = models.TextField(blank=True, verbose_name='错误信息')

    created_at = models.DateTimeField(auto_now_add=True, verbose_name="创建时间")
    updated_at = models.DateTimeField(auto_now=True, verbose_name="更新时间")

    class Meta:
        verbose_name = "音频整体分析"
        verbose_name_plural = "音频整体分析"
       
    def __str__(self):
        return f"Audio Analysis for Video Answer {self.video_answer.id}"


class AudioFrameData(models.Model):
    """音频帧数据模型 - 存储每秒的音高和音量数据及其对应的得分"""
    audio_analysis = models.ForeignKey(
        AudioAnalysis,
        on_delete=models.CASCADE,
        related_name='frame_data',
        verbose_name="关联音频分析"
    )
    timestamp = models.FloatField(verbose_name="时间戳（秒）")

    pitch = models.FloatField(null=True, blank=True, verbose_name="音高（Hz）")
    volume = models.FloatField(null=True, blank=True, verbose_name="音量（dB）")

    pitch_score_per_second = models.FloatField(null=True, blank=True, verbose_name="实时音高得分")
    volume_score_per_second = models.FloatField(null=True, blank=True, verbose_name="实时音量得分")

    created_at = models.DateTimeField(auto_now_add=True, verbose_name="创建时间")
    updated_at = models.DateTimeField(auto_now=True, verbose_name="更新时间")

    class Meta:
        verbose_name = "音频帧数据"
        verbose_name_plural = "音频帧数据"
        unique_together = ('audio_analysis', 'timestamp')
       
    def __str__(self):
        return f"Frame Data for Analysis {self.audio_analysis.id} at {self.timestamp}s"


class ExpressionAnalysis(models.Model):
    """表情分析结果存储"""
    video_answer = models.OneToOneField(
        VideoAnswer,
        on_delete=models.CASCADE,
        related_name='expression_analysis',
        verbose_name='关联视频回答',
        null=True,
        blank=True
    )
    
    # 视频分析主表字段
    video_path = models.CharField(max_length=500, verbose_name="视频路径")
    analysis_time = models.DateTimeField(default=timezone.now, verbose_name="分析时间")
    interval_seconds = models.IntegerField(verbose_name="提取间隔秒数")
    total_frames = models.IntegerField(verbose_name="分析帧总数")
    success_frames = models.IntegerField(verbose_name="成功分析帧数")
    average_concentration = models.FloatField(null=True, blank=True, verbose_name="平均专注度分数")
    max_score = models.FloatField(null=True, blank=True, verbose_name="最高分数")
    min_score = models.FloatField(null=True, blank=True, verbose_name="最低分数")
    overall_evaluation = models.CharField(max_length=100, null=True, blank=True, verbose_name="综合评价")

    # 统计摘要字段
    emotion_avg_score = models.FloatField(null=True, blank=True, verbose_name="情绪平均分数")
    emotion_high_ratio = models.FloatField(null=True, blank=True, verbose_name="情绪高分占比")
    pose_avg_score = models.FloatField(null=True, blank=True, verbose_name="姿态平均分数")
    pose_high_ratio = models.FloatField(null=True, blank=True, verbose_name="姿态高分占比")
    gaze_avg_score = models.FloatField(null=True, blank=True, verbose_name="视线平均分数")
    gaze_high_ratio = models.FloatField(null=True, blank=True, verbose_name="视线高分占比")
    
    # 分析状态
    analysis_status = models.CharField(
        max_length=20,
        choices=[
            ('pending', '待分析'),
            ('processing', '分析中'),
            ('completed', '已完成'),
            ('failed', '分析失败'),
        ],
        default='pending',
        verbose_name='分析状态'
    )
    error_message = models.TextField(blank=True, verbose_name='错误信息')
    
    # 分析时间戳
    analyzed_at = models.DateTimeField(auto_now_add=True, verbose_name='分析时间')
    
    def __str__(self):
        return f"表情分析 - {self.video_answer}"
    
    class Meta:
        verbose_name = '表情分析'
        verbose_name_plural = verbose_name


class ExpressionFrameData(models.Model):
    """帧分析详细表"""
    expression_analysis = models.ForeignKey(
        ExpressionAnalysis,
        on_delete=models.CASCADE,
        related_name='frame_data',
        verbose_name="表情分析"
    )
    frame_name = models.CharField(max_length=200, verbose_name="帧名称")
    frame_path = models.CharField(max_length=500, verbose_name="帧路径")
    concentration_score = models.FloatField(null=True, blank=True, verbose_name="专注度分数")
    analysis_status = models.CharField(max_length=100, verbose_name="分析状态")

    # 情绪分析字段
    primary_emotion = models.CharField(max_length=50, null=True, blank=True, verbose_name="主要情绪")
    emotion_confidence = models.FloatField(null=True, blank=True, verbose_name="情绪置信度")
    emotion_score = models.FloatField(null=True, blank=True, verbose_name="情绪评分")
    emotion_evaluation = models.CharField(max_length=100, null=True, blank=True, verbose_name="情绪评价")

    # 姿态分析字段
    yaw_angle = models.FloatField(null=True, blank=True, verbose_name="偏航角度")
    pitch_angle = models.FloatField(null=True, blank=True, verbose_name="俯仰角度")
    roll_angle = models.FloatField(null=True, blank=True, verbose_name="翻滚角度")
    pose_score = models.FloatField(null=True, blank=True, verbose_name="姿态评分")
    pose_evaluation = models.CharField(max_length=100, null=True, blank=True, verbose_name="姿态评价")

    # 视线分析字段
    left_gaze_angle = models.FloatField(null=True, blank=True, verbose_name="左眼视线角度")
    right_gaze_angle = models.FloatField(null=True, blank=True, verbose_name="右眼视线角度")
    avg_gaze_angle = models.FloatField(null=True, blank=True, verbose_name="平均视线角度")
    gaze_score = models.FloatField(null=True, blank=True, verbose_name="视线评分")
    gaze_evaluation = models.CharField(max_length=100, null=True, blank=True, verbose_name="视线评价")

    # 原始API数据
    api_raw_data = models.JSONField(null=True, blank=True, verbose_name="API原始数据")
    
    class Meta:
        verbose_name = '表情帧数据'
        verbose_name_plural = verbose_name
        ordering = ['frame_name']


class EmotionData(models.Model):
    """情绪详细数据表"""
    frame_analysis = models.OneToOneField(ExpressionFrameData, on_delete=models.CASCADE, related_name='emotion_detail',
                                          verbose_name="帧分析")
    happiness = models.FloatField(default=0.0, verbose_name="开心")
    surprise = models.FloatField(default=0.0, verbose_name="惊讶")
    neutral = models.FloatField(default=0.0, verbose_name="中性")
    sadness = models.FloatField(default=0.0, verbose_name="悲伤")
    anger = models.FloatField(default=0.0, verbose_name="愤怒")
    disgust = models.FloatField(default=0.0, verbose_name="厌恶")
    fear = models.FloatField(default=0.0, verbose_name="恐惧")

    class Meta:
        verbose_name = "情绪详细数据"
        verbose_name_plural = "情绪详细数据"


class InterviewReport(models.Model):
    """最终评估报告，汇集所有得分"""
    session = models.OneToOneField(
        InterviewSession,
        on_delete=models.CASCADE,
        related_name='report',
        verbose_name='关联会话'
    )
    
    # 综合得分和评语
    overall_score = models.FloatField(null=True, blank=True, verbose_name='综合得分')
    summary = models.TextField(blank=True, verbose_name='AI生成的综合评语')
    
    # 新增：HR评论
    hr_comments = models.TextField(blank=True, verbose_name='HR评论')
    hr_rating = models.PositiveSmallIntegerField(
        null=True, blank=True, 
        choices=[(i, str(i)) for i in range(1, 6)],  # 1-5分
        verbose_name='HR评分(1-5分)'
    )
    hr_recommendation = models.CharField(
        max_length=25,
        choices=[
            ('strongly_recommend', '强烈推荐'),
            ('recommend', '推荐'),
            ('neutral', '中立'),
            ('not_recommend', '不推荐'),
            ('strongly_not_recommend', '强烈不推荐'),
        ],
        blank=True,
        verbose_name='HR推荐结果'
    )
    
    # 新增：多模态分析结果汇总
    resume_match_score = models.FloatField(null=True, blank=True, verbose_name='简历匹配度得分')
    logical_thinking_score = models.FloatField(null=True, blank=True, verbose_name='逻辑思维能力得分')
    expression_avg_score = models.FloatField(null=True, blank=True, verbose_name='表达能力平均分')
    innovation_avg_score = models.FloatField(null=True, blank=True, verbose_name='创新能力平均分')
    professional_avg_score = models.FloatField(null=True, blank=True, verbose_name='专业技能平均分')
    stress_management_avg_score = models.FloatField(null=True, blank=True, verbose_name='压力应对平均分')
    
    # 新增：音频分析汇总
    audio_analysis_summary = models.JSONField(default=dict, verbose_name='音频分析汇总')
    
    # 新增：表情分析汇总
    expression_analysis_summary = models.JSONField(default=dict, verbose_name='表情分析汇总')
    
    # 新增：AI文本分析汇总
    text_analysis_summary = models.JSONField(default=dict, verbose_name='AI文本分析汇总')
    
    # 新增：最终决策
    final_decision = models.CharField(
        max_length=20,
        choices=[
            ('pass', '通过'),
            ('conditional_pass', '有条件通过'),
            ('fail', '不通过'),
            ('pending', '待定'),
        ],
        blank=True,
        verbose_name='最终决策'
    )
    
    # 新增：决策理由
    decision_reason = models.TextField(blank=True, verbose_name='决策理由')
    
    # 时间信息
    generated_at = models.DateTimeField(auto_now_add=True, verbose_name='生成时间')
    updated_at = models.DateTimeField(auto_now=True, verbose_name='更新时间')
    hr_reviewed_at = models.DateTimeField(null=True, blank=True, verbose_name='HR审核时间')
    
    def calculate_weighted_score(self):
        """计算加权总分"""
        if not self.overall_score:
            return None
            
        template = self.session.template
        weighted_score = (
            (self.resume_match_score or 0) * template.resume_match_weight +
            (self.professional_avg_score or 0) * template.professional_skill_weight +
            (self.logical_thinking_score or 0) * template.logical_thinking_weight +
            (self.innovation_avg_score or 0) * template.innovation_weight +
            (self.stress_management_avg_score or 0) * template.stress_management_weight +
            (self.expression_avg_score or 0) * template.expression_weight
        )
        return weighted_score
    
    def get_recommendation_by_score(self, score):
        """根据评分范围获取推荐结果"""
        if score >= 90:
            return '强烈推荐', '能力全面，实际经验丰富，技术/执行/创新均强'
        elif score >= 80:
            return '推荐录用', '基础扎实，部分能力突出，适合培养'
        elif score >= 70:
            return '谨慎考虑', '存在明显短板，需配合结构/支持团队弥补'
        else:
            return '不推荐', '不具备基本胜任力或缺乏关键经验'
    
    def update_final_decision(self):
        """更新最终决策"""
        weighted_score = self.calculate_weighted_score()
        if weighted_score is not None:
            recommendation, reason = self.get_recommendation_by_score(weighted_score)
            
            # 更新最终决策
            if recommendation == '强烈推荐':
                self.final_decision = 'pass'
            elif recommendation == '推荐录用':
                self.final_decision = 'pass'
            elif recommendation == '谨慎考虑':
                self.final_decision = 'conditional_pass'
            else:  # 不推荐
                self.final_decision = 'fail'
            
            self.decision_reason = reason
            self.save()

    def __str__(self):
        return f"Report for {self.session}"

    class Meta:
        verbose_name = '面试评估报告'
        verbose_name_plural = verbose_name


# #####################################################################
# # 5. 模拟面试与练习 (Mock Interview and Practice)
# #####################################################################

class PracticeSet(models.Model):
    """
    练习题集。用于组织和分类练习题目，对应前端的“专项练习类型”。
    例如：“前端基础知识”, “产品经理行为面试”等。
    """
    PRACTICE_TYPES = [
        ('logic', '逻辑题'),
        ('behavioral', '行为题'),
        ('technical', '技术题'),
    ]

    title = models.CharField(max_length=255, verbose_name='练习集标题')
    description = models.TextField(blank=True, verbose_name='描述')
    practice_type = models.CharField(max_length=20, choices=PRACTICE_TYPES, verbose_name='练习类型')
    difficulty = models.PositiveSmallIntegerField(default=1, verbose_name='难度 (1-5)')

    # 练习集可以包含笔试题和视频题
    logist_questions = models.ManyToManyField(
        LogistQuestion,
        blank=True,
        related_name='practice_sets',
        verbose_name='笔试题'
    )
    video_questions = models.ManyToManyField(
        VideoQuestion,
        blank=True,
        related_name='practice_sets',
        verbose_name='视频题'
    )

    def __str__(self):
        return self.title

    class Meta:
        verbose_name = '练习题集'
        verbose_name_plural = verbose_name


class PracticeSession(models.Model):
    """
    一次完整的模拟练习会话。
    记录用户选择的模式、使用的题集以及开始/结束时间。
    """
    PRACTICE_MODES = [
        ('quick', '快速练习'),
        ('targeted', '专项练习'),
        ('comprehensive', '综合练习'),
    ]

    user = models.ForeignKey(
        User,
        on_delete=models.CASCADE,
        related_name='practice_sessions',
        limit_choices_to={'role': 'candidate'},
        verbose_name='练习用户'
    )
    mode = models.CharField(max_length=20, choices=PRACTICE_MODES, verbose_name='练习模式')
    # 如果是专项练习，会关联一个特定的题集
    practice_set = models.ForeignKey(
        PracticeSet,
        on_delete=models.SET_NULL,
        null=True, blank=True,  # 非专项练习时可以为空
        related_name='sessions',
        verbose_name='所用题集'
    )
    started_at = models.DateTimeField(auto_now_add=True, verbose_name='开始时间')
    completed_at = models.DateTimeField(null=True, blank=True, verbose_name='完成时间')

    def __str__(self):
        return f"{self.user.name}'s practice session on {self.started_at.strftime('%Y-%m-%d')}"

    class Meta:
        verbose_name = '模拟练习会话'
        verbose_name_plural = verbose_name
        ordering = ['-started_at']


class PracticeAnswer(models.Model):
    """
    用户在一次模拟练习中对单个问题的回答。
    """
    session = models.ForeignKey(
        PracticeSession,
        on_delete=models.CASCADE,
        related_name='answers',
        verbose_name='所属练习会话'
    )
    # 一个回答可能对应笔试题或视频题，但不能同时对应两者。
    # 我们使用 content_type 来动态关联模型。
    logist_question = models.ForeignKey(LogistQuestion, on_delete=models.CASCADE, null=True, blank=True)
    video_question = models.ForeignKey(VideoQuestion, on_delete=models.CASCADE, null=True, blank=True)

    answer_text = models.TextField(blank=True, verbose_name='文本回答')
    video_url = models.URLField(blank=True, verbose_name='视频回答URL')
    is_skipped = models.BooleanField(default=False, verbose_name='是否跳过')
    answered_at = models.DateTimeField(auto_now_add=True)

    # AI对本次回答的即时反馈
    feedback = models.TextField(blank=True, verbose_name='AI反馈')
    score = models.FloatField(null=True, blank=True, verbose_name='单题得分')

    def __str__(self):
        return f"Answer in session {self.session.id}"

    class Meta:
        verbose_name = '练习回答'
        verbose_name_plural = verbose_name


# 替换PracticeAudioAnalysis模型字段为新音频分析字段
# 参考AudioAnalysis模型字段定义
class PracticeAudioAnalysis(models.Model):
    """练习音频分析结果存储"""
    practice_answer = models.OneToOneField(
        PracticeAnswer,
        on_delete=models.CASCADE,
        related_name='audio_analysis',
        verbose_name='关联练习回答'
    )
    
    # 语音转文字相关
    transcribed_text = models.TextField(null=True, blank=True, verbose_name="语音转文字内容")
    word_count = models.IntegerField(null=True, blank=True, verbose_name="转录字数/词数")
    speech_duration_seconds = models.FloatField(null=True, blank=True, verbose_name="实际说话时长（秒）")

    # 综合得分
    overall_audio_score = models.FloatField(null=True, blank=True, verbose_name="音频综合得分")

    # 语速分析
    speed_score = models.FloatField(null=True, blank=True, verbose_name="语速得分")
    speech_rate_syllables_per_second = models.FloatField(null=True, blank=True, verbose_name="语速（音节/秒）")

    # 音高分析
    pitch_score = models.FloatField(null=True, blank=True, verbose_name="音高得分")
    average_pitch_frequency_hz = models.FloatField(null=True, blank=True, verbose_name="平均基频（Hz）")

    # 音量分析
    volume_score = models.FloatField(null=True, blank=True, verbose_name="音量得分")
    average_volume_db = models.FloatField(null=True, blank=True, verbose_name="平均音量（dB）")

    # 停顿分析
    pause_score = models.FloatField(null=True, blank=True, verbose_name="停顿得分")
    total_pause_frequency_per_second = models.FloatField(null=True, blank=True, verbose_name="总停顿频次（次/秒）")

    # 流利度分析
    fluency_score = models.FloatField(null=True, blank=True, verbose_name="流利度总得分")
    articulation_rate_syllables_per_second = models.FloatField(null=True, blank=True, verbose_name="发音速率（音节/秒）")
    articulation_rate_score = models.FloatField(null=True, blank=True, verbose_name="发音速率得分")
    correction_count_per_second = models.FloatField(null=True, blank=True, verbose_name="修正次数（次/秒）")
    correction_count_score = models.FloatField(null=True, blank=True, verbose_name="修正次数得分")
    f2_slope_hz_per_ms = models.FloatField(null=True, blank=True, verbose_name="F2轨迹斜率（Hz/ms）")
    f2_slope_score = models.FloatField(null=True, blank=True, verbose_name="F2轨迹斜率得分")

    # 分析状态
    analysis_status = models.CharField(
        max_length=20,
        choices=[
            ('pending', '待分析'),
            ('processing', '分析中'),
            ('completed', '已完成'),
            ('failed', '分析失败'),
        ],
        default='pending',
        verbose_name='分析状态'
    )
    error_message = models.TextField(blank=True, verbose_name='错误信息')
    
    # 分析时间戳
    created_at = models.DateTimeField(auto_now_add=True, verbose_name="创建时间")
    updated_at = models.DateTimeField(auto_now=True, verbose_name="更新时间")
    
    def __str__(self):
        return f"练习音频分析 - {self.practice_answer}"
    
    class Meta:
        verbose_name = '练习音频分析'
        verbose_name_plural = verbose_name


class PracticeAudioFrameData(models.Model):
    """练习每秒音频切片数据"""
    audio_analysis = models.ForeignKey(
        PracticeAudioAnalysis,
        on_delete=models.CASCADE,
        related_name='frame_data',
        verbose_name='所属音频分析'
    )
    
    timestamp = models.FloatField(verbose_name='时间戳(秒)')
    pitch = models.FloatField(null=True, blank=True, verbose_name='音高(Hz)')
    volume = models.FloatField(null=True, blank=True, verbose_name='音量(dB)')
    
    class Meta:
        verbose_name = '练习音频帧数据'
        verbose_name_plural = verbose_name
        ordering = ['timestamp']
        unique_together = ['audio_analysis', 'timestamp']


class PracticeExpressionAnalysis(models.Model):
    """练习表情分析结果存储"""
    practice_answer = models.OneToOneField(
        PracticeAnswer,
        on_delete=models.CASCADE,
        related_name='expression_analysis',
        verbose_name='关联练习回答'
    )
    
    # 整体表情分析结果
    overall_emotion_vector = models.JSONField(default=dict, verbose_name='整体情绪向量')
    average_head_angle_x = models.FloatField(null=True, blank=True, verbose_name='平均头部X轴角度')
    average_head_angle_y = models.FloatField(null=True, blank=True, verbose_name='平均头部Y轴角度')
    average_head_angle_z = models.FloatField(null=True, blank=True, verbose_name='平均头部Z轴角度')
    average_eye_angle_x = models.FloatField(null=True, blank=True, verbose_name='平均眼神X轴角度')
    average_eye_angle_y = models.FloatField(null=True, blank=True, verbose_name='平均眼神Y轴角度')
    
    # 分析时间戳
    analyzed_at = models.DateTimeField(auto_now_add=True, verbose_name='分析时间')
    
    def __str__(self):
        return f"练习表情分析 - {self.practice_answer}"
    
    class Meta:
        verbose_name = '练习表情分析'
        verbose_name_plural = verbose_name


class PracticeExpressionFrameData(models.Model):
    """练习每秒表情切片数据"""
    expression_analysis = models.ForeignKey(
        PracticeExpressionAnalysis,
        on_delete=models.CASCADE,
        related_name='frame_data',
        verbose_name='所属表情分析'
    )
    
    timestamp = models.FloatField(verbose_name='时间戳(秒)')
    emotion_vector = models.JSONField(default=dict, verbose_name='情绪向量')
    head_angle_x = models.FloatField(null=True, blank=True, verbose_name='头部X轴角度')
    head_angle_y = models.FloatField(null=True, blank=True, verbose_name='头部Y轴角度')
    head_angle_z = models.FloatField(null=True, blank=True, verbose_name='头部Z轴角度')
    eye_angle_x = models.FloatField(null=True, blank=True, verbose_name='眼神X轴角度')
    eye_angle_y = models.FloatField(null=True, blank=True, verbose_name='眼神Y轴角度')
    
    class Meta:
        verbose_name = '练习表情帧数据'
        verbose_name_plural = verbose_name
        ordering = ['timestamp']
        unique_together = ['expression_analysis', 'timestamp']
